<?php
declare (strict_types = 1);

namespace app\middleware;

use think\Request;
use think\Response;

/**
 * 静态资源缓存控制中间件
 * 用于控制静态资源的缓存策略，确保用户获取最新资源
 */
class StaticCacheControl
{
    /**
     * 处理请求
     *
     * @param Request $request
     * @param \Closure $next
     * @return Response
     */
    public function handle($request, \Closure $next)
    {
        $response = $next($request);
        
        // 检查是否是静态资源请求
        $uri = $request->pathinfo();
        $isStaticResource = $this->isStaticResource($uri);
        
        if ($isStaticResource) {
            // 对于静态资源，设置适当的缓存控制头
            // 开发环境使用较短的缓存时间，生产环境可以使用更长的缓存时间
            $cacheTime = app()->isDebug() ? 3600 : 86400; // 1小时或1天
            
            $response->header([
                'Cache-Control' => "public, max-age={$cacheTime}",
                'Expires' => gmdate('D, d M Y H:i:s', time() + $cacheTime) . ' GMT',
                'ETag' => '"' . md5_file($this->getFilePath($uri)) . '"',
            ]);
            
            // 检查客户端缓存是否有效
            $ifNoneMatch = $request->header('If-None-Match');
            $etag = $response->getHeader('ETag');
            
            if ($ifNoneMatch && $ifNoneMatch === $etag) {
                return Response::create()->code(304);
            }
        } else {
            // 对于非静态资源，禁用缓存
            $response->header([
                'Cache-Control' => 'no-cache, no-store, must-revalidate',
                'Pragma' => 'no-cache',
                'Expires' => '0',
            ]);
        }
        
        return $response;
    }
    
    /**
     * 判断是否是静态资源
     *
     * @param string $uri
     * @return bool
     */
    private function isStaticResource(string $uri): bool
    {
        // 检查是否是静态资源目录
        $staticDirs = ['assets', 'static', 'css', 'js', 'images', 'fonts'];
        
        foreach ($staticDirs as $dir) {
            if (strpos($uri, $dir) === 0) {
                return true;
            }
        }
        
        // 检查文件扩展名
        $staticExtensions = ['js', 'css', 'png', 'jpg', 'jpeg', 'gif', 'svg', 'ico', 'woff', 'woff2', 'ttf'];
        $extension = strtolower(pathinfo($uri, PATHINFO_EXTENSION));
        
        return in_array($extension, $staticExtensions);
    }
    
    /**
     * 获取文件物理路径
     *
     * @param string $uri
     * @return string
     */
    private function getFilePath(string $uri): string
    {
        $publicPath = app()->getRootPath() . 'public' . DIRECTORY_SEPARATOR;
        return $publicPath . str_replace('/', DIRECTORY_SEPARATOR, $uri);
    }
}